#ifndef ___fat32_transacciones_funciones_auxiliares_2

#define ___fat32_transacciones_funciones_auxiliares_2 1

#include "f32_base.c"
#include "f32_bloq.c"
#include "f32_rbda.c"
#include "f32_tfa3.c"

int fat32_transaccion_esta_bloqueada(unsigned int);
unsigned char fat32_procesar_operacion(unsigned int, fat32_operacion);
unsigned int fat32_obtener_bloqueos_transaccion(unsigned int, fat32_bloqueo ***);
int fat32_procesar_bloqueo(fat32_bloqueo *);

int fat32_transaccion_esta_bloqueada (unsigned int transaccion) {
  fat32_bloqueo ** datosBloqueos;
  unsigned int cantidadBloqueos = fat32_obtener_bloqueos_transaccion(transaccion, &datosBloqueos);
  if (!cantidadBloqueos) return 0;
  unsigned int pos;
  int estado;
  for (pos = 0; pos < cantidadBloqueos; pos ++) {
    estado = fat32_procesar_bloqueo(datosBloqueos[pos]);
    if (estado) {
      cantidadBloqueos --;
      datosBloqueos[pos] = datosBloqueos[cantidadBloqueos];
      datosBloqueos = fb_cambiar_tamano(datosBloqueos, sizeof(fat32_bloqueo *), cantidadBloqueos);
    }
  }
  free(datosBloqueos);
  return cantidadBloqueos;
}

unsigned char fat32_procesar_operacion (unsigned int IDtransaccion, fat32_operacion operacion) {
  void * datos;
  void * datosE = operacion.datosEntrada;
  operacion.estado = (*(operacion.handler)) (IDtransaccion, datosE, &datos);
  if (operacion.estado) operacion.datosSalida = datos;
  return operacion.estado;
}

unsigned int fat32_obtener_bloqueos_transaccion (unsigned int transaccion, fat32_bloqueo *** buffer) {
  *buffer = NULL;
  unsigned int cant = 0;
  fat32_bloqueo * ref = fat32_bloqueos;
  unsigned int rem = fat32_cantidad_bloqueos;
  for (; rem; ref ++, rem --)
    if ((ref -> transaccionBloqueada) == transaccion) {
      *buffer = fb_cambiar_tamano(*buffer, sizeof(fat32_bloqueo *), ++ cant);
      (*buffer)[cant - 1] = ref;
    }
  return cant;
}

int fat32_procesar_bloqueo (fat32_bloqueo * bloqueo) {
  switch (bloqueo -> tipoEvento) {
  case 1:
    return fat32_procesar_bloqueo_lectura(bloqueo);
  case 2:
    return fat32_procesar_bloqueo_escritura(bloqueo);
  case 3:
    return fat32_procesar_bloqueo_acceso(bloqueo);
  case 4:
    return fat32_procesar_bloqueo_conexion(bloqueo);
  case 5:
    return fat32_procesar_bloqueo_apertura(bloqueo);
  default:
    return 1;
  }
}

#endif